package org.gruposp2p.aula.gwt.client.representation;

import java.util.ArrayList;
import java.util.List;
import org.gruposp2p.aula.gwt.client.content.GlassedDialog;
import org.gruposp2p.aula.gwt.client.event.AulaEventBus;
import org.gruposp2p.aula.gwt.client.event.CoursesChangeEvent;
import org.gruposp2p.aula.gwt.client.model.Course;
import org.gruposp2p.aula.gwt.client.model.Link;
import org.gruposp2p.aula.gwt.client.util.LinkConstants;
import org.restlet.gwt.Callback;
import org.restlet.gwt.Client;
import org.restlet.gwt.data.MediaType;
import org.restlet.gwt.data.Protocol;
import org.restlet.gwt.data.Request;
import org.restlet.gwt.data.Response;
import org.restlet.gwt.data.Status;
import org.restlet.gwt.resource.Representation;
import org.restlet.gwt.resource.StringRepresentation;
import org.restlet.gwt.resource.XmlRepresentation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.NodeList;
import com.google.gwt.xml.client.Text;
import com.google.gwt.xml.client.XMLParser;
import static org.gruposp2p.aula.gwt.client.util.XmlLabelConstants.*;

public class CoursesRepresentation {
	
	private static CoursesRepresentation instance = new CoursesRepresentation();
	private XmlRepresentation xmlRepresentation;
	
	private CoursesRepresentation () {}
	
	/**
	 * Method that reads the Courses representation
	 * <?xml version="1.0" encoding="UTF-8"?>
	 *	<courses>
     *		<course>
     *   		<description>Descripción curso 11</description>
     *   		<courseLink name="Curso 11" id="1" href="http://localhost:8888/course/1"/>
     *   		<coursegroups>
     *       		<coursegroupLink name="grupo 01" id="1" href="http://localhost:8888/course/1"/>
     *   		</coursegroups>
     *		</course>
     *		<course>
     *   		<description>Descripción curso 22</description>
     *   		<courseLink name="Curso 22" id="2" href="http://localhost:8888/course/1"/>
     *   		<coursegroups>
     *       		<coursegroupLink name="grupo 02" id="1" href="http://localhost:8888/course/1"/>
     *   		</coursegroups>
     *		</course>     
	 *	</courses>
	 * 
	 */
	public List<Course> getCoursesFromXmlRepresentation(XmlRepresentation xmlRepresentation) {
		 List<Course> courses = new ArrayList<Course>();
		 Document xmlDoc = xmlRepresentation.getDocument();
		 final Element root= xmlDoc.getDocumentElement();
		 XMLParser.removeWhitespace(xmlDoc);
		 NodeList coursesNodes = root.getElementsByTagName(COURSE_ELEMENT);
		 for (int i= 0; i < coursesNodes.getLength(); i++) {
			Course course = new Course();
			final Element courseElement = (Element)coursesNodes.item(i);
 		    final Element description =
			   	(Element)courseElement.getElementsByTagName(DESCRIPTION_ELEMENT).item(0);
		    final Element courseLinkElement =
			   	(Element)courseElement.getElementsByTagName(COURSELINK_ELEMENT).item(0);
		    Link courseLink = new Link();
		    courseLink.setId(courseLinkElement.getAttribute(ID_ATTRIBUTE));
		    courseLink.setHref(courseLinkElement.getAttribute(HREF_ATTRIBUTE));
		    courseLink.setName(courseLinkElement.getAttribute(NAME_ATTRIBUTE));
		    course.setLink(courseLink);
		    if (description != null) {
		    	course.setDescription(description.getFirstChild().getNodeValue());
		    }
 		    NodeList coursegroupsNodes = courseElement.getElementsByTagName(COURSEGROUPLINK_ELEMENT);
 		    if (coursegroupsNodes != null) {
 			    List<Link> coursegroupsLinks = new ArrayList<Link>();
 	 		    for (int j= 0; j < coursegroupsNodes.getLength(); j++) { 
 	 		    	Link coursegroupLink = new Link();
 	 		    	Element coursegroupElement = (Element)coursegroupsNodes.item(j);
 	 		    	if (coursegroupElement != null) {
 	 	 		    	coursegroupLink.setHref(coursegroupElement.getAttribute(HREF_ATTRIBUTE));
 	 	 		    	coursegroupLink.setId(coursegroupElement.getAttribute(ID_ATTRIBUTE));
 	 	 		    	coursegroupLink.setName(coursegroupElement.getAttribute(NAME_ATTRIBUTE));
 	 	 		    	coursegroupsLinks.add(coursegroupLink);
 	 		    	}
 	 		    }
 	 		    course.setCoursegroupsLinks(coursegroupsLinks);	
 		    }
			courses.add(course);	
		 }		 
		 return courses;
	}
	
	public void setXmlRepresentation(Document document) {
		//Element courseElement = xmlRepresentation.getDocument().getDocumentElement();
		GWT.log(document.toString(), null);
	}
	
	public XmlRepresentation getXmlRepresentation () {
		return xmlRepresentation; 
	}
	

	public Representation geRepresentation (List<Course> courses) {		
		StringRepresentation result = null;
	    Document xmlDoc = XMLParser.createDocument();
	    Element root = xmlDoc.createElement("aula");
	    Element coursesElement = xmlDoc.createElement("cursos");
	    for (Course course : courses) {
	    	Element courseElement = xmlDoc.createElement("curso");
	    	//courseElement.setAttribute("nombre", course.getName());
	    	Element courseElementDescription = xmlDoc.createElement("descripcion");
	    	Text descriptionTxt = xmlDoc.createTextNode(course.getDescription());
	    	courseElementDescription.appendChild(descriptionTxt);
	    	courseElement.appendChild(courseElementDescription);
	    	coursesElement.appendChild(courseElement);
	    }	    
	    root.appendChild(coursesElement);
	    result = new StringRepresentation(root.toString());
	    MediaType mediaType = new MediaType("application/vnd.gruposp2p.org.cursos_input+xml");
	    result.setMediaType(mediaType);
	    return result;
	}
	
	public static CoursesRepresentation getInstance() {
		return instance;
	}

	/*
	public void getHTTP () {
		Context context = new Context();
		List<Parameter> lista = new ArrayList<Parameter>(); 
		Parameter mediatype = new Parameter("Content-Type", "");
		lista.add(mediatype);
		context.setParameters(new Form(lista));
		final Client client = new Client(Protocol.HTTP);
		//client.setContext(context);
		client.get(AulaURIUtils.getCoursesResourceURI(), new Callback() {
			@Override
			public void onEvent(Request request, Response response) {
				GWT.log(response.getEntity().getText(), null);
					//setXmlRepresentation(response.getEntityAsXml());
				  	//Document document = response.getEntityAsXml().getDocument();
					CoursesChangeEvent coursesChangeEvent = new CoursesChangeEvent();
					coursesChangeEvent.setCourses(
							getCoursesFromXMlRepresentation(response.getEntityAsXml()));
					AulaEventBus.getInstance().fireEvent(coursesChangeEvent);			  
			  }}); 
	  }*/	 	
	
	public void getCourses () {
		GlassedDialog.getInstance().showLoadingCoursesDialog();
		final Client client = new Client(Protocol.HTTP);
		client.get(LinkConstants.getCoursesLink(), new Callback() {
			@Override
			public void onEvent(Request request, Response response) {
				Status status = response.getStatus();
				if (status.getCode() == Status.SUCCESS_OK.getCode()) {
					CoursesChangeEvent coursesChangeEvent = new CoursesChangeEvent();
					coursesChangeEvent.setCourses(
							getCoursesFromXmlRepresentation(response.getEntityAsXml()));	
					AulaEventBus.getInstance().fireEvent(coursesChangeEvent);		
					GlassedDialog.getInstance().hideDialog();					
				} else {
					GlassedDialog.getInstance().showErrorGettingResource(status);
				}
			}}); 
	}
	
	  public void postCourses (List<Course> courses) {
		  final Client client = new Client(Protocol.HTTP);
		  client.post(LinkConstants.getCoursesLink(), 
				  geRepresentation(courses), new Callback() {
			  @Override
			  public void onEvent(Request request, Response response) {
				  GWT.log("response.getStatus(): " + response.getStatus(), null);
			  }});
	  }
	  
}